﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using YiSah.Entity.Extension.User;
using YiSha.Cache.Factory;
using YiSha.Data.Repository;
using YiSha.Entity.OrganizationManage;
using YiSha.Entity.SystemManage;
using YiSha.Enums;
using YiSha.Enums.OrganizationManage;
using YiSha.Model.Param;
using YiSha.Model.Param.OrganizationManage;
using YiSha.Service.OrganizationManage;
using YiSha.SqlSugars;
using YiSha.Util;
using YiSha.Util.Model;

namespace YiSha.Service.OrganizationManage
{
    /// <summary>
    /// 用户服务类
    /// </summary>
    public class UserService : RepositoryFactory
    {

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="sysUser"></param>
        /// <returns></returns>
        public Task<TData<List<UserEntity>>> GetList(UserEntity sysUser)
        {
            var obj = new TData<List<UserEntity>>();
            var list = this.SqlSugarAdapters.GetList<UserEntity>(s => s.Valid);
            obj.Data = list;
            return Task.FromResult(obj);
        }
        /// <summary>
        /// 分页获取用户列表信息
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public Task<TData<List<UserEntityExtension>>> GetPageList(UserReq param)
        {
            var obj = new TData<List<UserEntityExtension>>() { Data = new List<UserEntityExtension>() };
            var expression = ExtLinq.True<UserEntityExtension>();
            expression = expression.And(a => a.Valid);
            if (!param.DepartmentId.IsEmpty())
            {
                expression = expression.And(a => a.DepartmentId == param.DepartmentId);
            }
            if (!param.UserName.IsEmpty())
            {
                expression = expression.And(a => a.UserName.Contains(param.UserName));
            }
            if (!param.Mobile.IsEmpty())
            {
                expression = expression.And(a => a.Mobile.Contains(param.Mobile));
            }
            if (param.userStatus_select != null)
            {
                expression = expression.And(a => a.UserStatus == param.userStatus_select);
            }
            if (param.StartTime.HasValue)
            {
                expression = expression.And(t => t.BaseCreateTime >= param.StartTime);
            }
            if (param.EndTime.HasValue)
            {
                param.EndTime = param.EndTime.Value.Date.Add(new TimeSpan(23, 59, 59));
                expression = expression.And(t => t.BaseCreateTime <= param.EndTime);
            }
            //查询用户信息
            var list = this.SqlSugarAdapters.GetPager(expression, param);
            obj.Data = list.Item2;
            //查询部门信息
            var deptList = SqlSugarAdapters.GetList<DepartmentEntity>(s => s.Valid);
            //查询角色信息
            var userIdList = list.Item2.Select(s => s.Id).ToList();
            var userBelong = SqlSugarAdapters.GetList<UserBelongEntity>(s => userIdList.Contains(s.UserId));
            obj.Data.ForEach(f =>
            {
                var deptIdList = f.DepartmentId.Split(",");
                var deptInfo = deptList.Where(w => deptIdList.Contains(w.Id)).OrderBy(o => o.BaseCreateTime).ToList();
                var userBelongInfo = userBelong.Where(w => w.UserId == f.Id).ToList();
                //获取角色信息
                var userRole = userBelongInfo.Where(w => w.BelongType == 2).ToList();
                //获取职位信息
                var userPosition = userBelongInfo.Where(w => w.BelongType == 1).ToList();
                f.DepartmentName = string.Join(">", deptInfo.Select(s => s.DepartmentName).ToList());
                f.RoleIds = string.Join(",", userRole.Select(s => s.BelongId).ToList());
                f.RoleName = string.Join(",", userRole.Select(s => s.BelongName).ToList());
                f.PositionIds = string.Join(",", userPosition.Select(s => s.BelongId).ToList());
                f.PositionName = string.Join(",", userPosition.Select(s => s.BelongName).ToList());
            });
            obj.Total = list.Item1;
            return Task.FromResult(obj);
        }
        public Task<TData<UserEntity>> GetUser(string id)
        {
            var obj = new TData<UserEntity>();
            var list = this.SqlSugarAdapters.GetEntity<UserEntity>(s => s.Id == id && s.Valid);
            obj.Data = list;
            return Task.FromResult(obj);
        }
        /// <summary>
        /// 校验用户登录
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="platform">登录客户端</param>
        /// <returns></returns>
        public Task<TData<UserEntity>> CheckLogin(string userName, string password, int platform)
        {
            TData<UserEntity> obj = new TData<UserEntity>();
            if (userName.IsEmpty() || password.IsEmpty())
            {
                obj.Msg = "用户名或密码不能为空";
                return Task.FromResult(obj);
            }
            var expression = ExtLinq.True<UserEntity>();
            expression = expression.And(t => t.UserName == userName);
            expression = expression.Or(t => t.Mobile == userName);
            expression = expression.Or(t => t.Email == userName);
            UserEntity user = this.SqlSugarAdapters.GetEntity(expression);
            if (user != null)
            {
                if (user.UserStatus == (int)StatusEnum.Yes)
                {
                    if (user.Password == EncryptUserPassword(password, user.Salt))
                    {
                        user.LoginCount++;
                        user.IsOnline = 1;

                        #region 设置日期
                        if (user.FirstVisit == GlobalConstant.DefaultTime)
                        {
                            user.FirstVisit = DateTime.Now;
                        }
                        if (user.PreviousVisit == GlobalConstant.DefaultTime)
                        {
                            user.PreviousVisit = DateTime.Now;
                        }
                        if (user.LastVisit != GlobalConstant.DefaultTime)
                        {
                            user.PreviousVisit = user.LastVisit;
                        }
                        user.LastVisit = DateTime.Now;
                        #endregion

                        switch (platform)
                        {
                            case (int)PlatformEnum.Web:
                                if (GlobalContext.SystemConfig.LoginMultiple)
                                {
                                    #region 多次登录用同一个token
                                    if (string.IsNullOrEmpty(user.WebToken))
                                    {
                                        user.WebToken = SecurityHelper.GetGuid();
                                    }
                                    #endregion
                                }
                                else
                                {
                                    user.WebToken = SecurityHelper.GetGuid();
                                }
                                break;

                            case (int)PlatformEnum.WebApi:
                                user.ApiToken = SecurityHelper.GetGuid();
                                break;
                        }
                        // await GetUserBelong(user);

                        obj.Data = user;
                        obj.Msg = "登录成功";
                        obj.MsgCode = MsgCode.Success;
                    }
                    else
                    {
                        obj.Msg = "密码不正确，请重新输入";
                    }
                }
                else
                {
                    obj.Msg = "账号被禁用，请联系管理员";
                }
            }
            else
            {
                obj.Msg = "账号不存在，请重新输入";
            }
            return Task.FromResult(obj);
        }
        /// <summary>
        /// 新增/修改
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<TData> SaveForm(UserEntityExtension entity)
        {
            TData obj = new TData() { };
            var db = SugarBase.GetInstance();
            try
            {
                if (ExistUserName(entity))
                {
                    obj.MsgCode = MsgCode.Fail;
                    obj.Msg = "用户名已经存在！";
                    return await Task.FromResult(obj);
                }
                //使用事务添加数据
                try
                {
                    entity.DepartmentIdAll = entity.DepartmentId;
                    //
                    var arr = entity.DepartmentIdAll.Split(',');
                    entity.DepartmentId = arr[arr.Length - 1];
                    //开始事务
                    db.BeginTran();
                    var userInfo = DictionaryMapUtils.Mapping<UserEntity, UserEntityExtension>(entity);
                    if (userInfo.Id.IsEmpty())
                    {
                        userInfo.Salt = GetPasswordSalt();
                        userInfo.Password = EncryptUserPassword(userInfo.Password, userInfo.Salt);
                        await userInfo.Create();
                        await db.Insertable(userInfo).ExecuteCommandAsync();
                    }
                    else
                    {
                        await db.Deleteable<UserBelongEntity>(t => t.UserId == userInfo.Id).ExecuteCommandAsync();
                        await entity.Modify();
                        //排除修改时的密码字段， 密码不进行更新，有单独的方法更新密码
                        await db.Updateable(userInfo).IgnoreColumns(it => new { it.Password, it.Salt }).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                    }
                    // 职位
                    if (!string.IsNullOrEmpty(entity.PositionIds))
                    {
                        var positionName = entity.PositionName.Split(',');
                        var positionIds = TextHelper.SplitToArray<string>(entity.PositionIds, ',');
                        for (int i = 0; i < positionIds.Length; i++)
                        {
                            UserBelongEntity positionBelongEntity = new UserBelongEntity()
                            {
                                UserId = userInfo.Id,
                                BelongId = positionIds[i],
                                BelongName = positionName[i],
                                BelongType = UserBelongTypeEnum.Position.ParseToInt(),
                            };
                            await positionBelongEntity.Create();
                            await db.Insertable(positionBelongEntity).ExecuteCommandAsync();
                        }
                    }
                    // 角色
                    if (!string.IsNullOrEmpty(entity.RoleIds))
                    {
                        var realName = entity.RoleName.Split(',');
                        var roleIds = TextHelper.SplitToArray<string>(entity.RoleIds, ',');
                        for (int i = 0; i < roleIds.Length; i++)
                        {
                            UserBelongEntity departmentBelongEntity = new UserBelongEntity()
                            {
                                UserId = userInfo.Id,
                                BelongId = roleIds[i],
                                BelongName = realName[i],
                                BelongType = UserBelongTypeEnum.Role.ParseToInt(),
                            };
                            await departmentBelongEntity.Create();
                            await db.Insertable(departmentBelongEntity).ExecuteCommandAsync();
                        }
                    }
                    await RemoveCacheById(userInfo.Id);
                    //提交事务
                    db.CommitTran();
                }
                catch (Exception ex)
                {
                    obj.MsgCode = MsgCode.Fail;
                    obj.Msg = ex.Message;
                    //回滚
                    db.RollbackTran();
                }
                return obj;
            }
            catch (Exception ex)
            {
                obj.MsgCode = MsgCode.Fail;
                obj.Msg = ex.Message;
                return obj;
            }
        }
        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Task<TData> DeleteForm(List<string> id)
        {
            TData obj = new TData();
            var row = this.SqlSugarAdapters.Delete<UserEntity>(s => id.Contains(s.Id));
            if (!row)
            {
                obj.MsgCode = MsgCode.Fail;
                obj.Msg = "操作失败，请稍后重试";
            }
            return Task.FromResult(obj);
        }
        /// <summary>
        /// 修改用户信息
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Task<TData> UpdateUser(UserEntity entity)
        {
            TData obj = new TData();
            var row = this.SqlSugarAdapters.Update(entity);
            if (row)
            {
                obj.MsgCode = MsgCode.Success;
            }
            return Task.FromResult(obj);
        }
        /// <summary>
        /// 校验用户名称账号是否存在
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool ExistUserName(UserEntity entity)
        {
            var expression = ExtLinq.True<UserEntity>();
            expression = expression.And(t => t.Valid);
            if (entity.Id.IsEmpty())
            {
                expression = expression.And(t => t.UserName == entity.UserName);
            }
            else
            {
                expression = expression.And(t => t.UserName == entity.UserName && t.Id != entity.Id);
            }
            return this.BaseRepository().IQueryable(expression).Count() > 0 ? true : false;
        }
        #region 私有方法
        /// <summary>
        /// 密码MD5处理
        /// </summary>
        /// <param name="password"></param>
        /// <param name="salt"></param>
        /// <returns></returns>
        public string EncryptUserPassword(string password, string salt)
        {
            string md5Password = SecurityHelper.MD5Encrypt(password);
            string encryptPassword = SecurityHelper.MD5Encrypt(md5Password + salt);
            return encryptPassword;
        }

        /// <summary>
        /// 密码盐
        /// </summary>
        /// <returns></returns>
        private string GetPasswordSalt()
        {
            return new Random().Next(1, 100000).ToString();
        }

        /// <summary>
        /// 移除缓存里面的token
        /// </summary>
        /// <param name="id"></param>
        private async Task RemoveCacheById(List<string> ids)
        {
            foreach (string id in ids)
            {
                await RemoveCacheById(id);
            }
        }
        /// <summary>
        /// 移除指定的缓存
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private async Task RemoveCacheById(string id)
        {
            var dbEntity = this.SqlSugarAdapters.GetEntity<UserEntity>(s => s.Id == id);
            if (dbEntity != null && !dbEntity.WebToken.IsEmpty())
            {
                CacheFactory.Cache.RemoveCache(dbEntity.WebToken);
            }
        }

        /// <summary>
        /// 获取用户的职位和角色
        /// </summary>
        /// <param name="user"></param>
        //private async Task GetUserBelong(SysUserEntity user)
        //{
        //    List<UserBelongEntity> userBelongList = await userBelongService.GetList(new UserBelongEntity { UserId = user.Id });

        //    List<UserBelongEntity> roleBelongList = userBelongList.Where(p => p.BelongType == UserBelongTypeEnum.Role.ParseToInt()).ToList();
        //    if (roleBelongList.Count > 0)
        //    {
        //        user.RoleIds = string.Join(",", roleBelongList.Select(p => p.BelongId).ToList());
        //    }

        //    List<UserBelongEntity> positionBelongList = userBelongList.Where(p => p.BelongType == UserBelongTypeEnum.Position.ParseToInt()).ToList();
        //    if (positionBelongList.Count > 0)
        //    {
        //        user.PositionIds = string.Join(",", positionBelongList.Select(p => p.BelongId).ToList());
        //    }
        //}
        #endregion
    }
}
